package com.tv.enoguia.fragment;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.loopj.android.http.AsyncHttpClient;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
import com.tv.enoguia.R;
import com.tv.enoguia.ShowDetailRouteActivity;
import com.tv.enoguia.Utils.DirectionsJSONParser;
import com.tv.enoguia.Utils.GPSTracker;
import com.tv.enoguia.bean.Celler;
import com.tv.enoguia.bean.ObjRoute;
import com.tv.enoguia.database.MySQLiteHelper;
import com.tv.enoguia.httpclient.MyJsonHttpResponseHandler;

public class DirectionFragment extends Fragment implements OnClickListener,
		OnTouchListener, LocationListener {

	TextView title, btnRoute,tittleDistance;
	// map
	private GoogleMap googleMap;
	private SupportMapFragment fragment;
	Location location;
	double mLatitude;
	double mLongitude;

	ImageButton btnBack;

	Celler celler = new Celler();
	
	double lonBus, latBus;
	private Marker mSelectedMarker;
    private boolean mRefreshingInfoWindow;
    
    DisplayImageOptions options = new DisplayImageOptions.Builder()
	.cacheInMemory(false).cacheOnDisc(true)
	.bitmapConfig(Config.RGB_565).build();
    
    float distance; 
    ImageButton btnMyLocation;
    MarkerOptions markerOptions;
    String url;
    
    ArrayList<String> objRoutes = new ArrayList<String>();
    
    GPSTracker gpsTracker;
   

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Bundle argument = getArguments();
		if (argument != null)
		{
			
		}

		
		celler = argument.getParcelable("celler");
		
		Log.i("DATA", "LAT: "+celler.getLat()+" LON:"+celler.getLon());
		
		lonBus = Double.parseDouble(celler.getLon());
		latBus = Double.parseDouble(celler.getLat());
		
		gpsTracker = new GPSTracker(getActivity());
		
		if (gpsTracker.canGetLocation) {
			gpsTracker.getLocation();
			mLatitude = gpsTracker.getLatitude();
			mLongitude = gpsTracker.getLongitude();
		} else {
			System.out.println("Unable");
		}
		
		
	}
	
	public static DirectionFragment newInstance() {
		DirectionFragment f = new DirectionFragment();
	    return f;
	}
	
	
	
	
	ViewGroup v;
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		try {
			if(v==null) {
				
				v = (ViewGroup) inflater.inflate(R.layout.activity_direction, container, false);
			} else {
				((ViewGroup) v.getParent()).removeView(v);
			}
			
			title = (TextView) v.findViewById(R.id.title);
			btnBack = (ImageButton) v.findViewById(R.id.btn_back);
			btnBack.setVisibility(View.VISIBLE);
			btnRoute = (TextView) v.findViewById(R.id.btn_route);
			btnRoute.setVisibility(View.VISIBLE);
			
			tittleDistance = (TextView) v.findViewById(R.id.title_distance);
			btnMyLocation = (ImageButton) v.findViewById(R.id.btn_my_location);
			
			// Getting status
			int status = GooglePlayServicesUtil
					.isGooglePlayServicesAvailable(getActivity().getBaseContext());
			// Showing status
			if (status == ConnectionResult.SUCCESS) {
				setUpMap();
				focusLocation();
			} else {
				Toast.makeText(getActivity(),
						"Google Play Services are not available",
						Toast.LENGTH_SHORT).show();
				int requestCode = 10;
				Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, getActivity(),
						requestCode);
				dialog.show();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		init();
		
		return v;
	}


	 @Override
	 public void onActivityCreated(Bundle savedInstanceState) {
	     super.onActivityCreated(savedInstanceState);
	     FragmentManager fm = getChildFragmentManager();
	     fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
	     if (fragment == null) {
	         fragment = SupportMapFragment.newInstance();
	         fm.beginTransaction().replace(R.id.map, fragment).commit();
	     }
	 }


	@Override
	public void onResume() {
		super.onResume();
		setUpMapIfNeeded();
	}
	
	private void setUpMapIfNeeded() {
		if (googleMap == null) {
			googleMap = fragment.getMap();
		}
		if (googleMap != null)
			setUpMap();
	}
	
	 private void setUpNewMap() {
		 googleMap.getUiSettings().setZoomControlsEnabled(false);
		 googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latBus, lonBus), 12.0F));
		 googleMap.addMarker(new MarkerOptions()
		   .position(new LatLng(latBus, lonBus))
		   .title(celler.getCellarName()).alpha(0.7F)
		   .icon(BitmapDescriptorFactory
		   .fromResource(R.drawable.pin_celler)));
		 
		 }

	void init() {
		title.setText("Map");
		btnBack.setOnTouchListener(this);
		btnRoute.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
//				openMap();
				Intent t = new Intent(getActivity(), ShowDetailRouteActivity.class);
				t.putStringArrayListExtra("route", objRoutes);
				t.putExtra("distance", String.valueOf(distance));
				startActivity(t);
			}
		});
		
		// tinh khoang cach
		
		
		Log.i("DATA", "My Location: "+mLatitude + " "+mLongitude);
		
		distance = distFrom(latBus, lonBus, mLatitude, mLongitude);
		
		tittleDistance.setText("Distancia "+distance+ " Km");
		btnMyLocation.setOnTouchListener(this);
	}

	@SuppressLint("NewApi")
	private void setUpMap() {
		// Do a null check to confirm that we have not already instantiated the
		// map.

			// Enabling MyLocation in Google Map
//			googleMap.setMyLocationEnabled(true);
//			googleMap.getUiSettings().setMyLocationButtonEnabled(false);

		 	googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latBus, lonBus), 12.0F));
			  // Creating an instance of MarkerOptions MarkerOptions
			 markerOptions = new MarkerOptions();
			 
			 // Setting position for the marker markerOptions.position(new
			  LatLng latLng = new LatLng(latBus, lonBus);
			 
			  markerOptions.position(latLng);
			  
			  
			  // Setting custom icon for the marker
			  markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin_celler));
			  
			  // Adding the marker to the map
			  googleMap.addMarker(markerOptions);
			  
			  
			  
			  
			 
			// Getting LocationManager object from System Service
			// LOCATION_SERVICE
			LocationManager locationManager = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);

			// Creating a criteria object to retrieve provider
			Criteria criteria = new Criteria();

			// Getting the name of the best provider
			String provider = locationManager.getBestProvider(criteria, true);
			
			googleMap.setInfoWindowAdapter(new MarkerInfoWindowAdapter());
			
			// Getting Current Location From GPS

			location = locationManager.getLastKnownLocation(provider);

			if (location != null) {
				onLocationChanged(location);
			}

			locationManager.requestLocationUpdates(provider, 20000, 0,
					new android.location.LocationListener() {

						@Override
						public void onStatusChanged(String provider,
								int status, Bundle extras) {
							// TODO Auto-generated method stub

						}

						@Override
						public void onProviderEnabled(String provider) {
							// TODO Auto-generated method stub

						}

						@Override
						public void onProviderDisabled(String provider) {
							// TODO Auto-generated method stub

						}

						@Override
						public void onLocationChanged(Location location) {
						}
					});
		// ve duong di
		drawRoute();
		

	}

	void focusLocation() {
		try {
			mLatitude = (float) location.getLatitude();
			mLongitude = (float) location.getLongitude();
			LatLng latLng = new LatLng(latBus, lonBus);


			googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
			googleMap.animateCamera(CameraUpdateFactory.zoomTo(10));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onLocationChanged(Location arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderDisabled(String arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		switch (v.getId()) {
		case R.id.btn_back:
			if (event.getAction() == MotionEvent.ACTION_UP) {
				getActivity().onBackPressed();
			}
			break;
		case R.id.btn_my_location:
			if (event.getAction() == MotionEvent.ACTION_UP) {
				/* googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new    
						   LatLng(location.getLatitude(),     
						   location.getLongitude()), 12));*/
				 googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new    
						   LatLng(mLatitude,     
						   mLongitude), 12));
			}
			break;

		default:
			break;
		}
		return false;
	}

	void openMap(){
		Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
				Uri.parse("http://maps.google.com/maps?   saddr="
						+ mLatitude + ","
						+ mLongitude + "&daddr="
						+ celler.getLat() + ","
						+ celler.getLon()));
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.addCategory(Intent.CATEGORY_LAUNCHER);
		intent.setClassName("com.google.android.apps.maps",
				"com.google.android.maps.MapsActivity");
		try {
			startActivity(intent);
		} catch (ActivityNotFoundException ex) {
			try {
				Intent unrestrictedIntent = new Intent(Intent.ACTION_VIEW,
						Uri.parse("http://maps.google.com/maps?   saddr="
								+ mLatitude + ","
								+ mLongitude + "&daddr="
								+ celler.getLat() + ","
								+ celler.getLon()));
				startActivity(unrestrictedIntent);
			} catch (ActivityNotFoundException innerEx) {
				Toast.makeText(getActivity(), "Please install a maps application",
						Toast.LENGTH_LONG).show();
			}
		}
	}
	
	@Override
	public void onClick(View arg0) {

	}
	
	 private void refreshInfoWindow() {
	        if (mSelectedMarker == null) {
	            return;
	        }
	        mRefreshingInfoWindow = true;
	        mSelectedMarker.showInfoWindow();
	        mRefreshingInfoWindow = false;
	    }
	
	public class MarkerInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
		public MarkerInfoWindowAdapter() {
			
		}

		@Override
		public View getInfoWindow(final Marker marker) {
			return null;
		}

		View v;
		@Override
		public View getInfoContents(final Marker marker) {
			if (!mRefreshingInfoWindow) {
                mSelectedMarker = marker;
                v = getActivity().getLayoutInflater().inflate(R.layout.maker_info, null, false);
	
				TextView cellarName = (TextView) v.findViewById(R.id.txt_name_bussiness);
				TextView towName = (TextView) v.findViewById(R.id.txt_town);
				final ImageView image = (ImageView) v.findViewById(R.id.img_bus);
				ImageLoader.getInstance().displayImage("http://enoguia.cat/img/fotos/"+celler.getPhoto(),
						image, options, new SimpleImageLoadingListener() {
	
							@Override
							public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
								super.onLoadingComplete(imageUri, view, loadedImage);
								Log.i("DATA", "---------------");
								//getInfoContents(marker);
								refreshInfoWindow();
							}
						});
				
				cellarName.setText(celler.getCellarName());
				towName.setText(celler.getTowName());
			}
			return v;
		}
	}
	
	public float distFrom(double latBus2, double lonBus2, double mLatitude2, double mLongitude2) {
	    double earthRadius = 6371; //kilometers
	    double dLat = Math.toRadians(mLatitude2-latBus2);
	    double dLng = Math.toRadians(mLongitude2-lonBus2);
	    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
	               Math.cos(Math.toRadians(latBus2)) * Math.cos(Math.toRadians(mLatitude2)) *
	               Math.sin(dLng/2) * Math.sin(dLng/2);
	    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
	    float dist = (float) (earthRadius * c);

	    return dist;
	    }
	
	
	public void drawRoute(){
		LatLng myLocattion = new LatLng(mLatitude, mLongitude);
//		LatLng myLocattion = new LatLng(latBus+0.1, lonBus+0.1);
		LatLng dest = new LatLng(latBus, lonBus);
		
		// Getting URL to the Google Directions API
        String url = getDirectionsUrl(myLocattion, dest);

        DownloadTask downloadTask = new DownloadTask();

        // Start downloading json data from Google Directions API
        downloadTask.execute(url);
		
	}
	
	private String getDirectionsUrl(LatLng origin,LatLng dest){
		 
        // Origin of route
        String str_origin = "origin="+origin.latitude+","+origin.longitude;
 
        // Destination of route
        String str_dest = "destination="+dest.latitude+","+dest.longitude;
 
        // Sensor enabled
        String sensor = "sensor=false";
 
        // Building the parameters to the web service
        String parameters = str_origin+"&"+str_dest+"&"+sensor;
 
        // Output format
        String output = "json";
 
        // Building the url to the web service
        url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;
        
        Log.i("DATA", "URL: "+url);
        
        return url;
    }
    /** A method to download json data from url */
    private String downloadUrl(String strUrl) throws IOException{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
            URL url = new URL(strUrl);
 
            // Creating an http connection to communicate with url
            urlConnection = (HttpURLConnection) url.openConnection();
 
            // Connecting to url
            urlConnection.connect();
 
            // Reading data from url
            iStream = urlConnection.getInputStream();
 
            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
 
            StringBuffer sb = new StringBuffer();
 
            String line = "";
            while( ( line = br.readLine()) != null){
                sb.append(line);
            }
 
            data = sb.toString();
 
            br.close();
 
        }catch(Exception e){
            Log.d("Exception while downloading url", e.toString());
        }finally{
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }
 
    // Fetches data from url passed
    private class DownloadTask extends AsyncTask<String, Void, String>{
 
        // Downloading data in non-ui thread
        @Override
        protected String doInBackground(String... url) {
 
            // For storing data from web service
            String data = "";
 
            try{
                // Fetching the data from web service
                data = downloadUrl(url[0]);
            }catch(Exception e){
                Log.d("Background Task",e.toString());
            }
            return data;
        }
 
        // Executes in UI thread, after the execution of
        // doInBackground()
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
 
            ParserTask parserTask = new ParserTask();
 
            // Invokes the thread for parsing the JSON data
            parserTask.execute(result);
        }
    }
 
    /** A class to parse the Google Places in JSON format */
    private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{
 
        // Parsing the data in non-ui thread
        @Override
        protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
 
            JSONObject jObject;
            List<List<HashMap<String, String>>> routes = null;
 
            try{
                jObject = new JSONObject(jsonData[0]);
                DirectionsJSONParser parser = new DirectionsJSONParser();
 
                // Starts parsing data
                routes = parser.parse(jObject);
                
                
            }catch(Exception e){
                e.printStackTrace();
            }
            return routes;
        }
 
        // Executes in UI thread, after the parsing process
        @Override
        protected void onPostExecute(List<List<HashMap<String, String>>> result) {
            ArrayList<LatLng> points = null;
            PolylineOptions lineOptions = null;
            MarkerOptions markerOptions = new MarkerOptions();
            
            parserRoute();
 
            // Traversing through all the routes
           try {
        	   for(int i=0;i<result.size();i++){
                   points = new ArrayList<LatLng>();
                   lineOptions = new PolylineOptions();
                   
    
                   // Fetching i-th route
                   List<HashMap<String, String>> path = result.get(i);
                   
                   
                   // Fetching all the points in i-th route
                   for(int j=0;j<path.size();j++){
                       HashMap<String,String> point = path.get(j);
    
                       double lat = Double.parseDouble(point.get("lat"));
                       double lng = Double.parseDouble(point.get("lng"));
                       LatLng position = new LatLng(lat, lng);
    
                       points.add(position);
                   }
    
                   // Adding all the points in the route to LineOptions
                   lineOptions.addAll(points);
                   lineOptions.width(8);
                   lineOptions.color(Color.RED);
               }
           	// Drawing polyline in the Google Map for the i-th route
               googleMap.addPolyline(lineOptions);
           } catch (Exception e) {
        	   e.printStackTrace();
           }
            	
        }
    }
    
    void parserRoute(){
    	AsyncHttpClient client = new AsyncHttpClient();
    	client.get(url, new MyJsonHttpResponseHandler(){

			@Override
			public void onFailure(Throwable error) {
				// TODO Auto-generated method stub
				super.onFailure(error);
			}

			@Override
			public void onSuccess(JSONObject re) {
				Log.i("DATA", "ROUTE: "+re.toString());
				try {
					JSONArray routes = re.getJSONArray("routes");
					JSONObject data = routes.getJSONObject(0);
					JSONArray legs = data.getJSONArray("legs");
					JSONObject legFull = legs.getJSONObject(0);
					JSONArray steps = legFull.getJSONArray("steps");
					for (int i = 0; i < steps.length(); i++) {
						Log.i("DATA", "DETAIL ROUTE: "+steps.getJSONObject(i).getString("html_instructions"));
						String step = steps.getJSONObject(i).getString("html_instructions");
						ObjRoute objRoute = new ObjRoute();
						
						objRoute.setStep(step);
						objRoutes.add(step);
					}
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
    		
    	});
    }
    
    
}
